Interactive CLI password prompt in PHP

Share this article

Just a quick tip, since I spent a good hour figuring this out recently. PHP has no native way of doing an interactive password prompt, when running as CLI. You can however use bash for the task. Of course this means that it won’t work on Windows, but you should be fine on most anything else. Edit: Using Windows Scripting Host, it’s possible to pop a prompt up for the user to type in. I’ve extended the example to use this technique for Windows based systems.


/**
 * Interactively prompts for input without echoing to the terminal.
 * Requires a bash shell or Windows and won't work with
 * safe_mode settings (Uses `shell_exec`)
 */
function prompt_silent($prompt = "Enter Password:") {
  if (preg_match('/^win/i', PHP_OS)) {
    $vbscript = sys_get_temp_dir() . 'prompt_password.vbs';
    file_put_contents(
      $vbscript, 'wscript.echo(InputBox("'
      . addslashes($prompt)
      . '", "", "password here"))');
    $command = "cscript //nologo " . escapeshellarg($vbscript);
    $password = rtrim(shell_exec($command));
    unlink($vbscript);
    return $password;
  } else {
    $command = "/usr/bin/env bash -c 'echo OK'";
    if (rtrim(shell_exec($command)) !== 'OK') {
      trigger_error("Can't invoke bash");
      return;
    }
    $command = "/usr/bin/env bash -c 'read -s -p ""
      . addslashes($prompt)
      . "" mypassword && echo $mypassword'";
    $password = rtrim(shell_exec($command));
    echo "n";
    return $password;
  }
}

Frequently Asked Questions (FAQs) about Interactive CLI Password Prompt in PHP

How can I create an interactive CLI password prompt in PHP?

Creating an interactive CLI password prompt in PHP involves using the readline() function. This function reads a line from the console and returns it. You can use it to prompt the user for a password. However, the password will be visible as the user types it. To hide the password, you can use the stty command to turn off echo, read the password, and then turn echo back on. Here’s a simple example:

echo 'Enter password: ';
system('stty -echo');
$password = trim(fgets(STDIN));
system('stty echo');
echo "\n";

What is the purpose of the stty -echo command?

The stty -echo command is used to disable the echoing of input characters. This means that when you type something on the command line, it won’t be displayed. This is particularly useful when prompting for passwords, as it prevents the password from being visible on the screen.

How can I handle errors when reading input from the user?

You can handle errors by checking the return value of the fgets() function. If fgets() fails, it will return false. You can check for this and display an error message if necessary. Here’s an example:

$password = trim(fgets(STDIN));
if ($password === false) {
echo "Error reading password\n";
exit(1);
}

Can I use the readline() function to read a password?

Yes, you can use the readline() function to read a password. However, readline() does not hide the password as the user types it. If you want to hide the password, you should use the stty -echo command as described above.

How can I validate the password entered by the user?

You can validate the password by comparing it to a known value. If the password entered by the user matches the known value, then the password is valid. Here’s an example:

$knownPassword = 'secret';
if ($password === $knownPassword) {
echo "Access granted\n";
} else {
echo "Access denied\n";
}

Can I prompt the user for input multiple times?

Yes, you can prompt the user for input multiple times by using a loop. You can use a while loop to keep prompting the user until they enter a valid password. Here’s an example:

do {
echo 'Enter password: ';
system('stty -echo');
$password = trim(fgets(STDIN));
system('stty echo');
echo "\n";
} while ($password !== $knownPassword);

How can I use the readline() function to read multiple lines of input?

The readline() function reads a single line of input. If you want to read multiple lines of input, you can use a loop. Here’s an example:

while ($line = readline()) {
// process $line
}

Can I use the readline() function in a web application?

No, the readline() function is not available in a web context. It is only available when running PHP from the command line. If you try to use readline() in a web application, you will get a fatal error.

How can I test my CLI application?

You can test your CLI application by running it from the command line and entering input as a user would. You can also write automated tests using a testing framework like PHPUnit.

Can I use the readline() function to read a file?

No, the readline() function is not designed to read files. It is designed to read input from the user on the command line. If you want to read a file, you should use functions like fopen(), fgets(), and fclose().

Troels Knak-NielsenTroels Knak-Nielsen
View Author

Troels has been crafting web applications, as a freelancer and while employed by companies of various sizes, since around the time of the IT-bubble burst. Nowadays, he's working on backend systems for a Danish ISP. In his spare time, he develops and maintains Konstrukt, a web application framework for PHP, and is the organizer of a monthly PHP-meetup in Copenhagen.

Share this article
Read Next
Get the freshest news and resources for developers, designers and digital creators in your inbox each week